package com.iteaj.iot.client.handle;

import com.iteaj.iot.client.*;
import com.iteaj.network.IotProtocolFactory;
import com.iteaj.network.Protocol;
import com.iteaj.network.client.AbstractClientProtocol;
import com.iteaj.network.client.ClientMessage;
import com.iteaj.network.event.ExceptionEvent;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

public class ClientProtocolHandle extends SimpleChannelInboundHandler<ClientMessage> {

    private ClientComponent clientComponent;
    private Logger logger = LoggerFactory.getLogger(ClientProtocolHandle.class);

    public ClientProtocolHandle(ClientComponent clientComponent) {
        this.clientComponent = clientComponent;
        if(this.clientComponent == null) {
            throw new IllegalArgumentException("ClientProtocolHandle必填参数[ClientComponent]");
        }
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ClientMessage msg) throws Exception {
        try {
            String componentName = clientComponent.getName();
            final IotProtocolFactory protocolFactory = clientComponent.protocolFactory();
            if(protocolFactory == null) {
                String deviceSn = msg.getHead().getEquipCode();
                logger.error("客户端协议处理({}) 协议工厂不存在 - 设备编号: {} - 报文: {}", componentName, deviceSn, msg);
                return;
            }

            Protocol protocol = protocolFactory.getProtocol(msg);
            if(protocol == null) {
                String messageId = msg.getMessageId();
                String deviceSn = msg.getHead().getEquipCode();
                logger.warn("客户端协议处理({}) {}获取不到协议(messageId={}) - 设备编号: {} - 报文: {}"
                        , componentName, protocolFactory.getClass().getSimpleName(), messageId, deviceSn, msg);
                return;
            }

            if(protocol instanceof TcpRequestProtocol) {
                ((TcpRequestProtocol<ClientMessage>) protocol).buildResponseMessage(msg);
            } else {
                logger.error("客户端协议处理({}) 错误协议 协议类型: {} - 说明: [{}]必须是[{}]的子类", componentName
                        , protocol.protocolType(), protocol.getClass().getSimpleName(), AbstractClientProtocol.class.getSimpleName());
            }
        } catch (Exception e) {
            this.exceptionCaught(ctx, e);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        IotClientBootstrap.publishApplicationEvent(new ExceptionEvent(cause, null));
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        IotClient client = clientComponent.getClient();
        if(client instanceof TcpSocketClient) {
            ((TcpSocketClient) client).reconnection(ctx.channel());
        }
    }
}
